home *** CD-ROM | disk | FTP | other *** search
Text File | 1985-03-28 | 49.5 KB | 1,484 lines |
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 1
-
-
-
- Tom Jennings
- 2269 Market Street #118
- San Francisco CA 94114
-
- FidoNet Node #1
- 415/864-1418
-
- INTENT
-
- This document is an attempt to describe and define
- the packet protocol used to support electronic mail under
- the Fido/FidoNet system.
-
- It will not describe or define Fido/Fidonet software
- operation, nor even describe what the system does; for that,
- I refer you to the following Fido manuals:
-
- Fido's Installation Manual (INSTALL.DOC)
- Fido's Operating Manual (FIDO.DOC)
- Fido's FidoNet Manual (FIDONET.DOC)
-
- Only the lower layers of the protocol will be
- discussed here; routing, forwarding, dialing algorithms and
- such will not be covered. These are mentioned, albeit
- briefly, in Fido's FidoNet Manual.
-
- BACKGROUND
-
- FidoNet was designed to be more or less portable
- within the existing "public domain" software base, ie. any
- system that can support binary transfers via XMODEM or it's
- variants is in theory capable of supporting FidoNet. This
- does not mean to imply that the current Fido/FidoNet
- software will be/can be transported to machines not
- currently supported; it means that no designed in
- limitations were intended.
-
- This document merely covers the algorithms used, and
- the problems encountered, in the automatic transfer of
- packets and files used by the MSDOS Fido/FidoNet system.
-
- DESCRIPTION
-
- FidoNet is a true electronic mail system supported
- by the Fido Bulletin Board System software, under MSDOS
- version 2. It's function is to transfer textual messages,
- and binary files, between physically seperate computers on
- an automatic, unattended basis.
-
- BASIC ASSUMPTIONS
-
- The basic unit of data in FidoNet, like most MSDOS
- and CPM software, is the byte, which here means 8 bits. All
- data transfers assume the availability of an 8 bit byte
- capable channel; 7 bit ASCII is not adequate. Parity, if
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 2
-
- used, must be transparent to the software.
-
- FidoNet is transaction oriented; a channel
- (connection) is made, data transferred, the channel closed.
- In all existing cases, this means a typical modem/phone line
- connection; dial, connect, transfer, disconnect, though
- anything that might be considered a "channel" will work.
-
- The most basic design criteria for FidoNet is
- extremely short channel connect times, since the usual
- channel is a telephone line, where costs are accumulated on
- a per minute basis. Lowest possible costs is the single most
- important issue here. For this reason, all packets are
- preassembled; no processing at all is done at packet
- transfer time.
-
- Due to the lack of real time operating systems,
- FidoNet runs on an alternating basis with Fido. While Fido
- is running, users enter messages, attach files and the like,
- to be later processed by FidoNet. When FidoNet gains control
- (at a predetermined time of day) it packetizes outgoing
- messages, then makes attempts to send these packets, and may
- receive packets from other nodes, all asynchronouously. When
- FidoNet's time slot is over, it deletes any un-sent packets,
- unpacks any packets that were received, and then passes
- control back to Fido. Note that incoming packets are not
- examined in any way until the FidoNet time slot is over.
-
- A basic concept in FidoNet is the "node". A node is
- any computer capable of sending or receiving FidoNet mail
- packets. All discussions of packet transfers here will
- assume point to point transfers.
-
- As background information, it should be noted that
- routing, forwarding, cost accounting, etc is done at a much
- higher layer; routing, for instance is done even before
- packets are created, and determines the destination node. It
- has no effect on packet transfer.
-
- SOFTWARE ASSUMPTIONS
-
- Fido/FidoNet is written in 'C' (Lattice flavor) and
- makes use (of course) of C style structures and strings.
- Luckily, these are quite simple. Here are the following
- basic components used throughout FidoNet:
-
- CHARACTERS:
- An 8 bit byte. The usual micro type "character"; all
- 8 bits may be signifigant. Usually 128ASCII.
-
- STRING:
- A one dimension array of 8 bit characters,
- terminated by a null. (hex 0) Some are of a fixed length; in
- this case, signifigant text is left justified, followed by
- the null, and the rest of the string is indeterminate. In
- practice, FidoNet strings vary from very few characters up
- to 4000 characters or so.
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 3
-
-
- INTEGERS:
- All integer variables are 16 bits ('C' shorts)
- unsigned, and are in Intel (big endian) format; least byte
- first in the byte stream.
-
- LONGS:
- A long integer is 32 bits, in Intel format.
-
- WHAT A PACKET IS
-
- A packet is a file that consists of a header, a
- variable amount of variable size messages, and a trailer.
- Each message within a packet has a header, and a single
- string of plain text.
-
- +---------------+
- | |
- | | Header
- | |
- +---------------+
- | | Message #1
- +---------------+
- | |
- / /
- / /
- | |
- +---------------+
- | | Message #N
- +---------------+
- | | Trailer
- +---------------+
-
-
- The header and trailer are of fixed length. All of
- the messages are variable length, but have a fixed number of
- fields within them.
-
- Packets must be treated as a byte stream; for many
- of the components, "type" flags determine the format of
- upcoming data, therefore it is difficult to "read ahead",
- except for buffering purposes.
-
- THE HEADER:
-
- The header is a fixed length structure, and contains
- the originating and destination nodes, the date the packet
- was made, a version number, and some extra space for future
- expansion.
-
- Foolishly, there is no "type" identifier in the
- packet header.
-
- A PACKET MESSAGE:
-
- Each message contains an interger "type", followed
- by the message fields. These are: attribute, originating
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 4
-
- node, destination node, two zeros, cost, date string, "to"
- string, "from" string, "Subject" string, followed by the
- text string.
-
- The type, attribute, orig and dest node numbers, the
- two zeros and cost are all integers. The other are serial
- byte streams, strings, of variable length.
-
- INPORTANT NOTE:
-
- Due to extreme shortsightedness in the original
- packet design, the message type 1 did not include the
- originating and destination node numbers; FidoNet inserted
- the node numbers found in the packet header when the message
- was unpacked and stored in the system.
-
- Routing meant that messages for many different nodes
- were packed into a single packet; needless to say this means
- that the node numbers may not be the same for each message,
- as was the previous assumtion.
-
- A message type 2 (the one described above) was added
- to accomodate the "extra" information. Starting in version
- 10, FidoNet will no longer create message type 1, though it
- will continue to receive them. Other implementations may
- ignore message type 1, and assume that all are message type
- 2.
-
- THE TRAILER:
-
- The trailer consists of a single integer 0. This can
- be thought of as a message type 0. This ends the packet; any
- data following it (as when XMODEM rounds the packet up to
- the next highest 128 bytes) should be ignored.
-
-
- SYSTEM ASSUMPTIONS
-
- Fido and FidoNet were designed using some basic
- software building block concepts, admittedly stolen from
- Ward Christensen's MODEM program.
-
- XMODEM with CRC error checking is used for the basic
- mail packet transfer. No further discussion will be made as
- to XMODEM implementation nor operation. Please refer to
- other documents.
-
- MODEM7, or more accurately, TELINK, protocol is used
- to transfer any files "attached" after the message packet.
- TELINK is identical to MODEM7, with the addition of an extra
- data block, that passes MSDOS dependent file information
- (time, date, exact file size) before the first data block.
- FidoNet is still MODEM7 capable; all that is necessary is to
- NAK the extra block, whose header character is ASCII SYN
- instead of SOH when receiving from a TELINK based FidoNet.
- For sending to TELINK based receiving FidoNets it is not
- necessary to send this extra block. This protocol is also
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 5
-
- described elsewhere.
-
-
- FidoNet assumes the presence of a clock of some
- sort, for failsafe monitoring of packet transfers, and for
- accounting purposes, to monitor actual connect times.
- Accounting is outside the scope of this document.
-
- A clock timer, preferably interrupt driven, is
- needed to monitor the initial connection process, though may
- be done using polled counters, if they are "calibrated".
- This is fairly important; it prevents excessive connect
- times if either the sender or receiver fails at any point.
-
-
- There are two basic subroutines used in the Fido
- implementation of FidoNet. While these are very low level
- hardware dependent routines, they are very important in
- concept.
-
- DELAY ( N )
-
- Delay for N centiseconds. This is just a time delay,
- or time waster routine. It is used for generating time
- delays for accomodating the telephone companies equipment.
-
- MODOUT ( CHARACTER )
-
- Send a character to the modem. This is shown for
- illustration purposes; it is used in the diagrams to follow.
-
- MODIN ( N )
-
- Receive a character from the mode, but wait no
- longer than N centiseconds. If a character is received, it
- is returned; if it times out, -1 is returned. Since
- characters are 8 bits, -1 (16 bits) indicates that no valid
- character was received. This is a very basic, very important
- function, upon which all of FidoNet is based.
-
- The centisecond timer does not need to be accurate.
- 10% or less error is ideal, 20% is acceptable, and Fidonet
- will usually still operate at up to 100% error. However,
- repeatability will suffer, and sensitivity to the "length"
- of a telephone connection will increase rapidly above 25%
- error.
-
- This is implemented on MSDOS as an interrupt driver
- timer; a polled timing loop is adequate if adjusted to match
- the processor speed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 6
-
- PACKET TRANSFERS
-
- Packet transfers will be described in two ways here;
- first, a prose description, lacking exact details, and a
- diagram with tables, with exact timing relationships and
- values.
-
- A FidoNet session consists of the following:
-
- - Building routing tables
-
- - Building list of active nodes
-
- - Creating packets
-
- - Compiling Messages
-
- - Compiling list of attached files
-
- - Sending/receiving Packets
-
- - Deleteing outgoing packets, marking sent messages
-
- - Unpacking incoming packets
-
- - Return control to Fido
-
- Only the creating of packets and attached file
- lists, their transmission and reception, and unpacking is
- covered here. The other steps are Fido dependent, and will
- vary from implementation to implementation.
-
-
- CREATING PACKETS:
-
- FidoNet makes a number of passes through all of the
- messages in the system. The first pass is merely to
- determine which nodes have messages destined to them. Each
- node is marked in a table, for later use in making packets
- and dialing.
-
- Additional passes are made, one for each node there
- is mail to. A packet file is created on disk, using the
- destination node number to create a unique filename (44.out
- for a packet to node 44, etc), and the packet header is
- written out.
-
- When a message to this node is found, the message is
- written out to the packet file. (The messages as stored in
- Fido are described later in detail)
-
- After the last message is written to the packet, the
- trailer is written out, the file closed.
-
- This process is repeated for all nodes that have
- mail to be sent.
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 7
-
- SENDING PACKETS:
- RECEIVING PACKETS:
-
- FidoNet alternates sending and receiving packets for
- most of the time slot. When it is not actually sending (or
- attempting to send) a packet, it is waiting for one.
-
- If there are no incoming calls, FidoNet makes
- outgoing calls at a random one or two minute interval. A
- node is chosen to call from the table compiled while making
- packets. A node is picked sequentially from this table,
- trying each one in sucession. When the end of the table is
- reached, it starts over at the beginning.
-
- When it is time to place a call, the next node is
- chosen from the table, the telephone number is dialed. If no
- connection is made, FidoNet goes back into receive mode.
-
- If a connection is made, CRs are sent, to determine
- the baud rate. When the called system determines the baud
- rate, it sends the "signon" message telling human callers it
- is not available. This message is detected by the caller,
- and terminates the baud detection. If baud is not detected
- in 8 seconds, the caller disconnects.
-
- The sender then waits for the line to clear (the
- signon message to stop), then sends a character designated
- as "TSYNC". This tells the receiver that it is a FidoNet
- node calling, instead of a human caller. There is a 60
- second limit placed on the TSYNC sequence. The receiver then
- goes into XMODEM file receive, with a unique name for the
- incoming packet. (0.in, 1.in ...)
-
- After sending TSYNC, the sender transmits the packet
- (N.OUT) using normal XMODEM protocol.
-
- After the packet is sent, the receiver goes
- immediately into MODEM7 mode, to receive any attached files.
-
- If there are no attached files, the sender sends an
- EOT, which when received by the receiver in MODEM7, tells it
- "no more files". If there are attached files, the sender
- sends all of the files in the attached file list, using
- MODEM7.
-
- After either sending the attached files, or after
- sending the EOT meaning no attached files, the sender delays
- five seconds, then disconnects. After receiving the last
- attached file (or the EOT) the receiver delays two seconds
- and disconnects. The delay is to accomodate the telephone
- systems peculiarity of keeping connect information on a
- seperate, faster, channel that the data itself; without the
- delay, it is possible for the "disconnect" to get there
- before the character does.
-
- If the packet was sent sucessfully, the sender
- deletes the outgoing packet, the attached file list, and
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 8
-
- marks the node table as "sucessful", and then returns to the
- receive and wait mode.
-
- UNPACKING PACKETS:
-
- When FidoNet mail time is over, any unsent outgoing
- packets are deleted, and all messages that were sent
- sucessfully are marked as SENT.
-
- Each incoming packet (0.in, 1.in ...) is unpacked
- and deleted. First, the destination node number is compared
- to the nodes actual number. If it does not match (this
- packet not really meant for this node) the packet is deleted
- without further unpacking. If it matches, the messages are
- unpacked and placed in the message area.
-
- The packet is read as a byte stream, and interpreted
- as read. When a message type is found, FidoNet assembles the
- message as it goes.
-
- Note that it is possible to receive part of a
- packet; Fidonet will unpack all complete messages and store
- them in the message area. It may find an error, such as an
- incomplete packet. This is not a necessary feature; since
- the packet was aborted, it will be sent again the next
- night.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 9
-
- FIDONET DIALING AND PACKET TRANSFER
-
- This is the final, detailed, description of the
- actual packet transfer. Some shorthand notation will be used
- here; "clock" means a general purpose timer for monitoring
- elapsed time, and is set and read during many parts of the
- packet protocol. The two subroutines described above are
- also used through out.
-
- The descriptions her are in a C like "pseudo code",
- for simplicity. Function or subroutine calls are shown as:
-
- function(parameter);
-
- Where function() is the subroutine, and "parameter"
- is a parameter passed to the function. Parameters here may
- be numeric values or strings, which can be determined from
- context. Functions without parameters are shown as
- function(). Functions may return a value, so that:
-
- x= function()
-
- Sets variable X to the value returned by function().
-
- IMPORTANT NOTE:
-
- Ther is one extremely important construct that does
- not, and cannot show up in these diagrams. This is a
- mechanism to monitor Carrier Detect on the modem, and return
- directly to a high level subroutine for error handling. This
- is important due to the huge number of place where carrier
- loss would have to be checked for, with the corresponding
- high number of error return checks.
-
- This can be implemented with a C like "set_jmp",
- which stores the stack pointer and a return address, and
- jumps to the return address if carrier is lost.
-
- Also, in the Fido implementation, this error exit is
- taken when the clock goes over the set limit. This frees the
- high level code from having to watch the clock constantly.
-
- The actual high level packet receive and send C
- source is included at the end of this document to hopefully
- make this a bit clearer.
-
-
- All mnemonics are standard ASCII control characters,
- with the exception of "TSYNC", described below.
-
- Control Character Definitions
-
- Char Hex Dec
- ---- --- ---
- CR 0d 13
- EOT 04 4
- TSYNC ae 174
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 10
-
-
-
- PACKET TRANSMISSION:
-
- send_packet:
-
- Attempt to place the call. If no connection, just return,
- where FidoNet will wait for an incoming call, or delay one
- or two minutes to place the next outgoing call.
-
- set baud rate from node list
- dial phone number,
- if no connection, return
-
- A connection has been made. Determine the baud rate first.
- This "whacks return" up to eight times; if no message
- appears from whacking, it stops and calls it an error. The
- "double whack" (sic) seems to work better than a single CR.
- When the receiver determines the baud rate, it sends 4 CRs,
- and the signon message, which also contains CRs. The sender
- notices this and stops sending its CRs.
-
- for (i= 1 to 8) {
- send CR, delay(20), send CR;
- if (modin(100) == CR) break out of loop;
- }
-
- if (no CR received above) {
- mark table as one "connect",
- disconnect,
- return.
- }
-
- Baud rate is now detected. Set the failsafe timer, wait
- until the line clears (the signon message stops coming),
- then send TSYNC. If one minute elapses, disconnect and
- return.
-
- print ("Connected");
-
- set clock to zero;
- while (clock is less than one minute) {
- if (modin(50) == -1) break out of loop;
- }
- if clock == one minute {
- disconnect,
- return.
- }
-
- send (TSYNC);
- disable clock;
- print ("Sent TSYNC");
-
- Presumably, all connected now. Start sending the packet via
- XMODEM. XMODEM will timeout after so many tries, so that
- this will not hang if the other end fails or is not a
- FidoNet.
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 11
-
-
- print "Sending Packet"
- xmodem send (packet);
-
- Packet transmission complete. Mark the in memory table as
- "succesful". If there are attached files, send them now,
- otherwise just send an EOT.
-
- success= 1;
-
- if (attached files)
- modem7 send attached files
-
- else send EOT.
-
- All sent, delay 5 seconds to let things settle down.
-
- delay(500)
- disconnect,
- return.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 12
-
- PACKET RECEPTION:
-
- Carrier was detected while waiting to place a call or
- waiting for an incoming call. Determine baud rate first,
- display the signon message, then wait for TSYNC. There is a
- one minute limit waiting for TSYNC. Note that connect()
- watches the clock while waiting for CRs, and will take a
- fatal error abort if it goes over the set limit. This
- example therefore assumes that it will not timeout.
-
- receive_packet:
-
- reset clock,
- connect() determine baud rate
-
- print to modem:
- "FidoNet Version x.x
- FidoNet Node #N
- Processing mail Only"
-
- while (clock less than one minute) {
- if modin(100) == TSYNC break out of loop;
- }
-
- if (over one minute) {
- disconnect,
- return;
- }
-
- All connected, received TSYNC. Wait for the incoming packet.
- Each incoming packet is named sequentially, starting at 0;
- 0.in, 1.in, 2.in, etc. If no packet was received, quite now;
- no sense in trying to get attached files if no packet
- received.
-
- xmodem receive packet
- if no files received {
- disconnect,
- return.
- }
-
- Since it may have taken a few seconds to close up and write
- out the packet file, the sender may have sent extra EOTs
- from the end of the XMODEM packet transfer. Delay a bit, and
- flush out the modem.
-
- delay(200),
- flush modem,
-
- Now just go right into MODEM7 receive, for any attached
- files. If there are none, the sender will send us an EOT,
- which tells MODEM7 there are no more files. It can also just
- hang up at this point, since the packet has already been
- received. After the last, if any, file(s) received, delay 2
- seconds and disconnect.
-
- receive modem7 *.*
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 13
-
- delay(200),
- disconnect,
- return.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 14
-
- IMPLEMENTATION NOTES:
-
- These are some suggestions on implementing FidoNet
- on all systems. They are merely suggestions; obviously you
- can do what you want.
-
-
- LOW LEVEL FUNCTIONS:
-
- As mentioned before, there are some low level
- functions that at least some of which are probably
- universal. The ideas below may make it easier to implement a
- "bullet proof" FidoNet.
-
- ELAPSED TIME CLOCK:
-
- This is a necessity, in one form or another. It's
- accuracy does not need to be high. In Fido, it is
- implemented as a timer tick interrupt, that increments in
- memory variables: 'millisecs', 'seconds', 'minutes', and a
- function to clear the clock, ie. set the above counters to
- zero. (millisec is almost never actuall milliseconds; on the
- IBM PC, for instance, the clock tick is at 55.55 mS; 55 is
- added to 'millisec' every clock tick.)
-
- There is an additional variable called 'limit', that
- is the time limit to enforce for a particular routine.
- Setting it to zero effectively disables the limit.
-
- Thirdly, there is a function called limitchk(), that
- does two things:
-
- 1. Watches the set time limit vs. the minute counter
-
- 2. Watches the carrier detect line from the modem
-
- If either one of these events happens, it takes the
- fatal error trap, and returns directly, instead of returning
- normally.
-
-
- limitchk() {
-
- if (limit > 0) {
- if (minutes >= limit) frc_abort();
- }
- if ! dsr()) frc_abort();
- }
-
- frc_abort() is the fatal error jump, back to the
- caller directly. dsr() is a function that returns false (0)
- if carrier is lost. If no fatal errors, limitchk() just
- returns.
-
-
- MODIN(N)
- MODOUT()
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 15
-
-
- These two are the lowest level character IO in Fido.
- modin(N) returns either a character from the modem, or -1
- (TIMEOUT) if no character was available within N
- centiseconds. This avoids hanging forever waiting for a
- character that may never come.
-
- modout() merely sends a character to the modem.
-
- Both of these functions check for errors by calling
- limitchk() while waiting for input or output ready.
-
- modin(n)
- int n;
- {
- millisec= 0L;
- while (millisec < (10 * n) ) {
- if (character ready) return(modem char);
- limitchk();
- }
- return(-1);
- }
-
- modout(c)
- char c;
- {
- while (output not ready) {
- limitchk();
- }
- send char to modem
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 16
-
- MESSAGES
-
- While the message format is very Fido dependent, it
- may be illustrative to show the correspondence between a
- "normal" Fido message and one that has been installed in a
- packet.
-
- This is the format of a Fido message, as contained
- in any Fido Message Area.
-
-
- /* Message header structure. The message text is just a long
- string. */
-
- struct _msg {
- char from[36]; /* who from, */
- char to[36]; /* who to, */
- char subj[72]; /* message subject, */
- char date[20]; /* creation date, */
- int times; /* number of times read, */
- int dest; /* destination node, */
- int orig; /* originating node */
- int cost; /* actual cost of msg */
- int caca[6]; /* extra space, */
- unsigned reply; /* thread to previous */
- int attr; /* message type, */
- int up; /* thread to next */
- };
-
- /* The message text starts at the byte following the end
- of the structure, and is terminated by a single null. */
-
- /* Bit values for msg.attr */
-
- #define MSGPRIVATE 1 /* private message, */
- #define MSGREAD 4 /* read by addressee */
- #define MSGSENT 8 /* sent OK (remote) */
- #define MSGFILE 16 /* file attached to msg */
- #define MSGFWD 32 /* being forwarded */
- #define MSGORPHAN 64 /* unknown dest node */
- #define MSGKILL 128 /* kill after mailing */
-
-
- A Fido message is 191 bytes minimum; 190 bytes of
- header, above, and a variable amount of message text, null
- terminated. A fairly large klunky thing to pass around. When
- compacted into a packet, it is much smaller. As an example,
- assume the following message:
-
- From: Tom Jennings On Fido 1
- To: John Madill On Fido 2
- Subject: Test message
- This is text in the test message.
-
- A hex dump of this test message follows. Note that
- the null terminated strings are followed by garbage; please
- ignore it.
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 17
-
-
- 54 6F 6D 20 4A 65 6E 6E-69 6E 67 73 00 00 8E 36 Tom Jennings...6
- 00 00 00 FE FF 06 00 00-00 00 96 36 31 00 F3 21 ...~.......61.s!
- 0A 00 00 00 4A 6F 68 6E-20 4D 61 64 69 6C 6C 00 ....John Madill.
- 86 99 F8 27 86 99 02 28-00 00 91 36 57 61 69 74 ..x'...(...6Wait
- 20 2E A0 99 AE 16 68 21-74 65 73 74 20 6D 65 73 . ...h!test mes
- 73 61 67 65 00 00 65 00-FF 00 FC FF 00 00 B8 99 sage..e...|...8.
- 40 00 AF 06 AF 06 65 06-40 00 65 00 65 00 FC FF @././.e.@.e.e.|.
- 00 00 AF 06 0D 06 40 00-65 00 FF 00 FC FF 00 00 ../...@.e...|...
- DA 99 65 00 AF 06 7E 60-1D 1A 83 F2 99 36 BC 27 Z.e./.~`...r.6<'
- 32 33 20 4F 63 74 20 38-34 20 20 31 36 3A 31 39 23 Oct 84 16:19
- 3A 34 38 00 01 00 02 00-01 00 1B 00 00 00 00 00 :48.............
- 00 00 00 00 00 00 00 00-00 00 81 00 00 00 20 20 ..............
- 54 68 69 73 20 69 73 20-74 65 78 74 20 69 6E 20 This is text in
- 74 68 65 20 74 65 73 74-20 6D 65 73 73 61 67 65 the test message
- 2E 0D 0A 0D 0A 00 ......
-
- When the message is packetized, it becomes much
- smaller; an entire packet, header, the above message and
- trailer, is only 164 bytes. The extra space and most of the
- Fido dependent items are removed.
-
- 01 00 02 00 C0 07 09 00-02 00 10 00 19 00 0E 00 ....@...........
- 00 00 01 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
- 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
- 00 00 00 00 00 00 00 00-00 00 01 00 01 00 1B 00 ................
- 32 33 20 4F 63 74 20 38-34 20 20 31 36 3A 31 39 23 Oct 84 16:19
- 3A 34 38 00 4A 6F 68 6E-20 4D 61 64 69 6C 6C 00 :48.John Madill.
- 54 6F 6D 20 4A 65 6E 6E-69 6E 67 73 00 74 65 73 Tom Jennings.tes
- 74 20 6D 65 73 73 61 67-65 00 20 20 54 68 69 73 t message. This
- 20 69 73 20 74 65 78 74-20 69 6E 20 74 68 65 20 is text in the
- 74 65 73 74 20 6D 65 73-73 61 67 65 2E 0D 0A 0D test message....
- 0A 00 00 00 ....
-
- The packet header format is as follows. It is
- possible to follow, and hand disassemble, the message
- packet.
-
- struct _hdr {
- int orig; /* originating Node # */
- int dest; /* destination node */
- int year,month,day,hour,minute,second;
- int rate; /* baud rate */
- int ver; /* packet version */
- int extra[19];
- } pkthdr;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 18
-
- #include <stdio.h>
- #include <ctype.h>
- #include <bbs.h>
- #include <xfbuf.h>
- #include <ascii.h>
- #include <xtelink.h>
-
- #define TSYNC 0xae
-
- extern char ver[];
-
- extern unsigned crcmode; /* 1 if CRC mode, */
- extern unsigned filemode; /* transfer type; XMODEM, MODEM7, TELINK */
-
- /* Statistics on file transmission. */
-
- extern unsigned totl_files; /* total files sent/rec'd */
- extern unsigned totl_failures; /* how many failed, */
- extern unsigned totl_errors; /* error count, soft errors incl */
- extern unsigned totl_blocks; /* number blocks sent, */
-
- extern int minutes,seconds;
- extern int pktnum; /* incoming packet number */
-
- extern struct _route route[ROUTE_SIZE]; /* routing table */
- extern int maxnode; /* number of nodes in route table */
-
- extern struct _sched sched[SCHEDS]; /* scheduled events */
- extern char tag; /* handy local copy of the tag */
- extern int event; /* handy local copy of the current event */
-
- extern struct _nmap nmap[MAXNODES]; /* working node table */
- extern int nn; /* current node, */
- extern int nodetotal; /* number of nodes in the table */
-
- extern struct _pkthdr pkthdr; /* FidoNet packet header */
- extern struct _mail mail; /* MAIL.SYS */
- extern struct _node node; /* in memory node descriptor */
- extern struct _sys sys;
-
- extern char *_txbuf; /* message display buff, ASCII upload */
-
- extern int sysfiles; /* total system files, */
-
- extern int overwrite; /* 1 == allow overwriting files */
- extern int xferdisp; /* 1 == display up/dn load status */
-
- extern int rate; /* baud rate */
- extern int cd_flag;
- extern int limit;
-
- /* Carrier detected. Determine the baud rate, display a message to
- tell humans what were doing, then get in sync with the sender. Once
- in sync, receive the mail packet.
-
- The kludge 'state' tells us what point we reached, for logging. */
-
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 19
-
- rcv_mail() {
-
- int i,n;
- char pktname[80],*cp;
- int msg_pkts,msg_blocks;
- int state;
-
- gtod(pktname);
- cprintf("\r\n * Incoming Call at %s\r\n",pktname);
- lprintf("\r\n * Incoming Call at %s\r\n",pktname);
-
- /* We get an abort if: timeout, no sync (human caller), actual file transfer
- error, or packet received and sender hangs up. Totl_files is 0 if no
- packets transferred. */
-
- totl_blocks= 0;
- totl_files= 0;
- msg_pkts= 0;
- msg_blocks= 0;
- clr_clk(); /* reset the clock, */
- limit= 1; /* limit to connect, */
- cd_flag= 0; /* watch Carrier Detect */
- state= 0; /* nothing yet */
-
- set_abort(0); /* trap carrier loss here, */
- if (was_abort()) {
- if (state == 0) {
- cprintf(" * Never determined Baud Rate\r\n");
- lprintf(" * Never determined Baud Rate\r\n");
-
- } else if (state == 1) {
- cprintf(" * Caller not a FidoNet\r\n");
- lprintf(" * Caller not a FidoNet\r\n");
-
- } else if (msg_pkts == 0) {
- cprintf(" * Error during packet transfer\r\n");
- lprintf(" * Error during packet transfer\r\n");
-
- } else {
- cprintf(" * Received packet\r\n");
- lprintf(" * Received packet\r\n");
- if (totl_files > 0) {
- lower_dtr();
- cprintf(" * Received %u files\r\n",totl_files);
- lprintf(" * Received %u files\r\n",totl_files);
- sprintf(pktname,"%u.fli",pktnum);
- i= _xcreate(pktname,2);
- if (i == -1) {
- cprintf(" * Can't create %s\r\n",pktname);
- lprintf(" * Can't create %s\r\n",pktname);
-
- } else {
- _xwrite(i,_txbuf,strlen(_txbuf));
- _xclose(i);
- }
- raise_dtr();
- }
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 20
-
- }
- cd_flag= 0; /* real CD, */
- if (cd()) discon(); /* hang up, delay for telco */
- else delay(200); /* delay for telco */
-
- return(msg_pkts);
- }
-
- /* The sender whacks CR until it gets a CR back. It then waits for the
- message to stop, sends a TSYNC, and starts the transfer. */
-
- /* -------------------- One Minute to Complete This ---------------------- */
-
- /* The CRs and message must be sent all at once; the receiver is looking
- for a quiet line, so any delays casued by logging, etc will foul things
- up. */
-
- cprintf(" * Determining Baud Rate\r\n");
- lprintf(" * Determining Baud Rate\r\n");
- connect();
- state= 1; /* DETERMINED BAUD RATE */
-
- cprintf(" * FidoNet Signon Message\r\n");
- for (i= 5; i--;) modout(CR);
- sprintf(_txbuf," FidoNet Node #%u Version %s\r\n",mail.node,ver);
- cp= _txbuf; while (*cp) modout(*cp++);
- sprintf(_txbuf," Processing mail only, call back later.\r\n");
- cp= _txbuf; while (*cp) modout(*cp++);
-
- cprintf(" * Connected at %d baud, waiting for sync\r\n",rate);
- lprintf(" * Connected at %d baud, waiting for sync\r\n",rate);
- for (i= 30; i--;) {
- n= modin(100); /* 30 sec to get TSYNC */
- if (n == TSYNC) break;
- limitchk(); /* double check */
- }
- if (n != TSYNC) frc_abort(); /* no TSYNC */
- state= 2; /* GOT TSYNC */
-
- /* ------------------- End One Minute to Complete -------------------- */
-
- /* All connected. Transfer the mail packet. No time limit, but the
- file receive will abort if there is an error. */
-
- limit= 0; /* no time limit */
-
- sprintf(pktname,"%u.in",++pktnum); /* pick a new name, */
- cprintf(" * Waiting for Mail Packet\r\n");
- lprintf(" %s ",pktname);
-
- crcmode= 1; /* CRC, */
- filemode= XMODEM; /* file xfer mode, */
- *_txbuf= '\0'; /* received file name */
- recieve(pktname); /* receive a packet, */
-
- msg_pkts= totl_files;
- msg_blocks= totl_blocks; /* number of mail packets, */
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 21
-
- totl_files= 0;
- totl_blocks= 0;
- if (msg_pkts == 0) { /* if nothing received */
- frc_abort(); /* terminate here */
- }
-
- /* Let extra EOTs, etc settle out, then flush it so the file receive
- doesnt get the extra EOTs. */
-
- while (modin(10) != TIMEOUT);
-
- /* Wait for any incoming files. If there areent any, then the caller
- will just hang up if an older version, or will send EOT if no files. */
-
- filemode= TELINK;
- *_txbuf= '\0'; /* get list of uploaded files */
- recieve(mail.filepath); /* get any files, */
- delay(200);
- frc_abort(); /* error trap exit */
- }
-
- /* Send a mail packet to the remote. Dial the number, if error, return 0 to
- indicate no connection. Also, 'minutes' upon return reflects the actual
- connection time. */
-
- send_mail() {
-
- char pktname[80],floname[80];
- int n,f;
- int msg_pkts,msg_blocks;
- int state;
-
- gtod(pktname);
- cprintf("\r\n * Calling Fido%u %s %s at %s\r\n",node.number,node.name,node.phone,pktname);
- lprintf("\r\n * Calling Fido%u %s %s at %s\r\n",node.number,node.name,node.phone,pktname);
-
- sprintf(floname,"%u.flo",node.number);
- *_txbuf= '\0'; /* in case no file, */
- f= _xopen(floname,0); /* read in file list, */
- if (f != -1) {
- n= _xread(f,_txbuf,_TXSIZE);
- _txbuf[n]= '\0'; /* null terminate it, */
- _xclose(f);
- }
-
- sprintf(pktname,"%u.out",node.number); /* local packet to send */
- ++nmap[nn].tries; /* log another try, */
-
- /* We get an abort if (1) it times out dialing, (2) we fail to connect
- or (3) transmission sucessful, and receiver hung up. totl_files tells
- us what happened. */
-
- totl_blocks= 0;
- totl_files= 0;
- msg_pkts= 0;
- msg_blocks= 0;
- state= 0; /* no connect yet */
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 22
-
-
- set_abort(0);
- if (was_abort()) {
- if (state > 0) {
- nmap[nn].time+= (minutes * 60) + seconds;
- ++nmap[nn].connects;
- }
-
- if (state == 0) {
- cprintf(" * No connection\r\n");
- lprintf(" * No connection\r\n");
-
- } else if (state == 1) {
- cprintf(" * Disconnect before synchronization\r\n");
- lprintf(" * Disconnect before synchronization\r\n");
-
- } else if (msg_pkts == 0) {
- cprintf(" * No packet(s) sent; probable non FidoNet system\r\n");
- lprintf(" * No packet(s) sent; probable non FidoNet system\r\n");
-
- } else {
- cprintf(" * Sent %u packets %u files\r\n",msg_pkts,totl_files);
- lprintf(" * Sent %u packets %u files\r\n",msg_pkts,totl_files);
- nmap[nn].success= 1;
- _xdelete(pktname); /* done with that packet */
- _xdelete(floname);
- }
-
- cd_flag= 0;
- if (cd()) discon();
-
- return(msg_pkts);
- }
-
- /* Set the baud rate from the node list, and dial the number. Dialing is
- aborted if either a no-connect from the modem, or a timeout if no modem
- is connected. */
-
- rate= 300; /* assume 300 baud, */
- if (node.rate >= 1200) rate= 1200; /* unless higher */
- baud(rate);
- cd_flag= 1; /* dont bomb on no carrier */
-
- /* -------------------- One Minute to Dial ---------------------- */
-
- limit= 1; /* 1 min to dial, */
- clr_clk(); /* reset the clock, */
- if (dial(node.phone) == 0) {
- frc_abort();
- }
-
- rate= 300; /* again for stupid hardware */
- if (node.rate >= 1200) rate= 1200; /* that dials at fixed rates */
- baud(rate);
- cprintf(" * Connected at %d baud\r\n",rate);
- lprintf(" * Connected at %d baud\r\n",rate);
- state= 1; /* CONNECTION MADE */
-
-
-
-
-
-
-
- Fidonet Electronic Mail Protocol 8 Feb 85 Page 23
-
-
- /* -------------------- One Minute to Connect and Sync --------------- */
-
- /* Send CRs until we get a CR back, saying we detected baud correctly. */
-
- clr_clk(); /* reset clock, */
- limit= 1; /* 1 min to connect, etc */
- cd_flag= 0; /* now watch carrier */
-
- delay(300); /* let modems settle */
- mflush(); /* flush buffers */
-
- /* Extremely noisy lines never settle (Fido 79), so just delay to
- let the modems connect, then flush the buffers of any garbage.
-
- while (modin(300) != TIMEOUT) /* quiet line, */
- limitchk();
- */
- for (n= 10; --n;) { /* limited tries for baud test */
- modout(CR); /* send CR CR until we */
- delay(20); /* get one back, */
- modout(CR);
- if (modin(100) == CR) break;
- }
- if (n == 0) {
- cprintf(" * No response to whacking CR\r\n");
- lprintf(" * No response to whacking CR\r\n");
- frc_abort();
- }
-